/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Recommender.PLSI;

import DataModel.ArrDataModel;
import IO.ReadFile;
import java.io.IOException;

/**
 *
 * @author tuyetphuong
 */
public class PLSI_Method {

    public int Sonhom;
    public int Sodoituong;
    public int Songuoidung;
    float[]pzu;
    float psz;

    /**
     * @param args the command line arguments
     */
    public float[] Init() {
        pzu = new float[Songuoidung + 1];
        for (int i = 0; i <= Songuoidung; i++) {
            if(Sonhom!=0)
            {
            pzu[i] = (float) (1.0 / Sonhom);
            }
        }
        return pzu;
    }

    public float[][][] Init1() {
        float[][][] pzus = new float[Sonhom + 1][Sodoituong + 1][Songuoidung + 1];
        for (int i = 1; i < Sonhom; i++) {
            for (int j = 1; j <= Sodoituong; j++) {
                for (int k = 1; k <= Songuoidung; k++) {
                    pzus[i][j][k] = 1;
                }
            }
        }
        return pzus;
    }

    public float psu(int s, int u, ArrDataModel arr) {

        float[] pzu = Init();
        float psu = 0;
        int count = 0;
        psz = 0;
        int lap = 0;
        while (lap < 1) {
            for (int z = 0; z < Sonhom; z++) {
                for (int i = 0; i < arr.numofrow; i++) {
                    if (arr.arrmodel.get(i).GetIDItem() == s && arr.arrmodel.get(i).iRating==1) {
                        count++;
                    }
                }


                psz = (float) (1.0 * count / arr.numofrow);

            }
            lap++;
        }
        psu = psu + (psz * pzu[u]);
        return psu;

    }

    public void Init_PLSI(ArrDataModel arr) throws IOException {

        arr.GetNumOFItem();
        arr.GetNumOFUser();
        Sonhom = arr._MaxUser / 40;
        Sodoituong = arr._MaxItem + 800;
        Songuoidung = arr._MaxUser + 800;
    }

    public void UpDate(int u, int s, ArrDataModel arr)
    {
        int count=0;
        for (int z = 0; z < Sonhom; z++) {
                for (int i = 0; i < arr.numofrow; i++) {
                    if (arr.arrmodel.get(i).GetIDItem() == s && arr.arrmodel.get(i).iRating==1) {
                        count++;
                    }
                }

                psz = (float) (1.0 * (count+1) / arr.numofrow);

            }

    }
    public float GetPoint_PLSI(int u, int s, ArrDataModel arr) {
        float p=psu(s, u, arr)*1000;
        if(p>1)
        {
            p=1;
        }
        if(p<0.01)
        {
            p=(float) 0.01;
        }
        return p;
    }

    public static void main(String[] args) throws IOException {
        // TODO code application logic here

        float f;
        int sotuvandung = 0;
        int sotuvan = 0;
        int sodanhgia = 0;
        int sodanhgiadung = 0;
        int taptest = 0;
        float recall = 0;
        float precsion = 0;
        float mae = 0;
        float rmse = 0;
        int solantuvanrecall = 0;
        int solantuvanprecsion = 0;
        ArrDataModel arr = new ArrDataModel();
        ReadFile readfile = new ReadFile();
        arr = readfile.ReadTrainFile("u6.base");
        //    arr.GetNumOFItem();
        //  arr.GetNumOFUser();
        System.out.print(arr.numofrow);
        ArrDataModel arr1 = new ArrDataModel();
        ReadFile readfile1 = new ReadFile();
        arr1 = readfile.TestFile20();
        arr1.GetNumOFItem();
        arr1.GetNumOFUser();
        PLSI_Method plsi = new PLSI_Method();
        plsi.Sodoituong=arr._MaxItem+1;
        plsi.Songuoidung=arr._MaxUser+1;
        plsi.Sonhom=10;
        plsi.Init_PLSI(arr);
        taptest = arr1.numofrow;
        for (int i = 0; i < arr1.numofrow; i++) {
            if (plsi.GetPoint_PLSI(arr1.arrmodel.get(i).iIDUser, arr1.arrmodel.get(i).iIDItem, arr) >= 0.007) {
                sodanhgiadung++;
            }
        }
        float p = (float) 0.0;
        p = (taptest - sodanhgiadung);
        p = p / taptest;
        mae = p;
        System.out.print(mae);
        System.out.print("\n");
        p = (float) Math.sqrt(p);
        rmse = p;
        System.out.print(rmse);
        System.out.print("\n");
        p = (float) Math.sqrt(p);
        int[] itemset = arr1.GetItemSet();
        int[] userset = arr1.GetUserSet();
        for (int i = 0; i < userset.length; i++) {
            int[] taptuvan = new int[1000];
            sotuvan = 0;
            int[] ratingset = arr1.UserRating(userset[i]);
            for (int j = 0; j < itemset.length; j++) {
                if (plsi.psu(itemset[j], userset[i], arr) >= 0.015) {
                    if(taptuvan.length<1000){
                    taptuvan[sotuvan] = itemset[j];
                    sotuvan++;
                    }
                }
            }
            sotuvandung = 0;
            for (int ii = 0; ii < ratingset.length; ii++) {
                for (int j = 0; j < sotuvan; j++) {
                    if (ratingset[ii] == taptuvan[j]) {
                        sotuvandung++;
                    }
                }
            }
            if (ratingset.length != 0) {
                recall += (float) sotuvandung / (float) ratingset.length;
                solantuvanrecall++;
            }
            if (sotuvan != 0) {
                precsion += (float) sotuvandung / (float) sotuvan;
                solantuvanprecsion++;
            }
        }
        recall = (float) recall / (float) solantuvanrecall;
        System.out.print(recall);
        System.out.print("\n");
        precsion = (float) precsion / (float) solantuvanprecsion;
        System.out.print(precsion);
        System.out.print("\n");
        f = 2 * recall * precsion / (recall + precsion);
        System.out.print(f);
        System.out.print("\n");
        for( int i =1; i<=100; i++){
        plsi.UpDate(1, 1, arr);
        System.out.print(plsi.GetPoint_PLSI(3, i, arr));
        System.out.print("\n");
        }
    }
}
